<!-- 日历插件 -->
<template>
  <div class="calendar">
    <!-- 标题-->
    <div class="title_top">
      <div class="text">{{ title }}</div>
    </div>
    <div class="calendar_bottom">
      <!-- 年份 月份 -->
      <div class="calendar_b_month">
        <ul>
          <!--上一年 (点击会触发pickPre函数，重新刷新当前日期) -->
          <li
            class="calendar_arrow"
            @click="pickDate(currentYear, currentMonth, false, true)"
          >
            <a-icon type="double-left" />
          </li>
          <!-- 上一月 -->
          <li
            class="calendar_arrow"
            style="margin-left: 0px"
            @click="pickDate(currentYear, currentMonth, false, false)"
          >
            <a-icon type="left" />
          </li>
          <li class="year_month">
            <span class="choose-month">
              <span
                class="choose_month_year"
                @click="openChangeYear(currentYear, true)"
                >{{ currentYear }}年</span
              >
              <span
                class="choose_month_month choose_month_year"
                @click="openChangeYear(currentMonth, false)"
              >
                {{
                  currentMonth >= 10 ? currentMonth : `0${currentMonth}`
                }}月</span
              >
            </span>
          </li>
          <!-- 下一月 -->
          <li
            class="calendar_arrow"
            style="margin-right: 0px"
            @click="pickDate(currentYear, currentMonth, true, false)"
          >
            <a-icon type="right" />
          </li>
          <!-- 下一年 -->
          <li
            class="calendar_arrow"
            @click="pickDate(currentYear, currentMonth, true, true)"
          >
            <a-icon type="double-right" />
          </li>
        </ul>
      </div>
      <div v-if="!boolChangeDate">
        <!-- 星期 -->
        <ul class="calendar_b_weekdays">
          <li>一</li>
          <li class="special_margin_weekdays">二</li>
          <li>三</li>
          <li>四</li>
          <li class="special_margin_weekdays">五</li>
          <li>六</li>
          <li>日</li>
        </ul>
        <!-- 日期 -->
        <ul class="calendar_b_days">
          <!-- 核心 v-for循环 每一次循环用<li>标签创建一天 -->
          <li
            v-for="(dayObject, dayIndex) in days"
            :key="dayIndex"
            :class="{
              default_days: true,
              active_days: isActiveDys(dayObject.day), //活跃日期
              special_margin_days: dayIndex % 7 == 1 || dayIndex % 7 == 4, //marginLeft:13px
              no_current_month_day:
                dayObject.day.getMonth() + 1 != currentMonth, //非当月
              future_days: isFuture(dayObject.day), //未来日期
            }"
            @click="selectedDate(dayObject.day.getDate())"
          >
            <span>
              {{ dayObject.day.getDate() }}
            </span>
          </li>
        </ul>
      </div>
      <div v-else>
        <ul
          class="calendar_b_select scroll_style"
          ref="calendarSelectScroll"
          :style="{ height: `${calendarBotHeight}px` }"
        >
          <li
            v-for="selectItem in arrYearOrMonthSelect"
            :key="`${selectItem.type}_${selectItem.value}`"
            :class="{
              calendar_select_default: true,
              calendar_select_active:
                `${selectItem.type}_${selectItem.value}` === strChangeActive,
            }"
            @click="
              selectYearOrMonth(
                selectItem.value,
                selectItem.type == 'year' ? currentMonth : currentYear,
                selectItem.type
              )
            "
          >
            <span>
              {{ selectItem.value
              }}{{ selectItem.type == "year" ? "年" : "月" }}
            </span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import moment from "moment";
export default {
  components: {},
  name: "calendar_components",
  data() {
    return {
      currentDay: 1,
      currentMonth: 1,
      currentYear: 1970,
      currentWeek: 1,
      days: [],
      strChangeActive: "", //选择日期面板
      boolChangeDate: false, //是否打开切换日期面板
      boolChangeClickType: "", //打开切换日期面板类型
      arrYearOrMonthSelect: [], //待选择年份或月份
      haveRowNum: 0, //当页拥有行数
    };
  },
  props: ["activeDays", "title"],
  //监控data中的数据变化
  watch: {},
  computed: {
    // 内容高
    calendarBotHeight() {
      return this.haveRowNum * 34 + 44 + 24;
    },
  },
  created() {
    this.initData(null);
  },
  mounted() {},
  methods: {
    /**
     * 生成日历数组
     * @param cur 默认每月第一天或选择的日期
     */
    initData(cur) {
      let date;
      if (cur) {
        date = new Date(cur);
      } else {
        let now = new Date();
        date = new Date(
          this.formatDate(now.getFullYear(), now.getMonth() + 1, 1)
        );
      }
      this.currentDay = date.getDate();
      this.currentYear = date.getFullYear();
      this.currentMonth = date.getMonth() + 1;
      this.currentWeek = date.getDay() == 0 ? 7 : date.getDay(); //获取当前日期是星期几 1...6,0
      let str = this.formatDate(
        this.currentYear,
        this.currentMonth,
        this.currentDay
      );
      this.haveRowNum = this.handleDateHaveRow(str, this.currentWeek);
      this.days.length = 0;
      // 今天是周日，放在第一行第7个位置，前面6个

      //初始化本周
      for (let i = this.currentWeek - 1; i >= 0; i--) {
        let d = new Date(str);
        // 将月份中的某一天设置为日期对象(0:上月最后一天，-1：上月倒数第二天，以此类推)
        d.setDate(d.getDate() - i);
        let dayObject = {}; //用一个对象包装Date对象  以便为以后预定功能添加属性
        dayObject.day = d;
        this.days.push(dayObject); //将日期放入data 中的days数组 供页面渲染使用
      }
      //其他周
      for (let i = 1; i <= this.haveRowNum * 7 - this.currentWeek; i++) {
        let d = new Date(str);
        d.setDate(d.getDate() + i);
        let dayObject = {};
        dayObject.day = d;
        this.days.push(dayObject);
      }
    },
    /**
     *获取当前日期共有多少行
     * @param currentDate 传入需要计算的日期时间 例如：2024-05-21
     * @param currentWeek 当前日期是星期几
     */
    handleDateHaveRow(currentDate, currentWeek) {
      //获取当前月天数
      const daysInMonth = moment(currentDate).daysInMonth();
      const currentWeekIndex = currentWeek - 1;
      //第一行 起始位置到结束个数
      const firstRowDays = 7 - currentWeekIndex;
      //当前整数行数
      const rowQuotient = Math.floor((daysInMonth - firstRowDays) / 7);
      //当前整数行的余数
      const rowRemainder = (daysInMonth - firstRowDays) % 7;
      //共有多少行
      let rowNum = rowRemainder === 0 ? rowQuotient + 1 : rowQuotient + 2;
      //一号位于星期日时
      //   rowNum = currentWeekIndex < 0 ? rowNum + 1 : rowNum;
      return rowNum;
    },
    /**
     * 是否是未来日期
     * @param judgeDate 需要判断的日期
     */
    isFuture(judgeDate) {
      return moment(judgeDate, "YYYY-MM-DD").isAfter();
    },
    /**
     * 是否是活跃日期
     * @param judgeDate 需要判断的日期
     */
    isActiveDys(judgeDate) {
      const _judgeDate = moment(judgeDate).format("YYYY-MM-DD");
      return this.activeDays.indexOf(_judgeDate) !== -1 ? true : false;
    },

    /**
     * 切换月份或年份
     * @param year
     * @param month
     * @param isNext true:表示切换到下一个月份或年份
     * @param isYear true:切换的是年份
     */
    pickDate(year, month, isNext, isYear) {
      let d;
      if (isNext) {
        d = isYear
          ? new Date(year + 1, month, 0)
          : new Date(year, month + 1, 0);
      } else {
        d = isYear
          ? new Date(year - 1, month, 0)
          : new Date(year, month - 1, 0);
      }
      this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1));
    },
    /**
     * 选择指定年月
     * @param curYear
     */
    openChangeYear(curDate, isYear) {
      // 再次点击关闭
      if (this.boolChangeDate && this.boolChangeClickType === isYear) {
        this.boolChangeDate = !this.boolChangeDate;
        return;
      }
      this.strChangeActive = `${isYear ? "year" : "month"}_${curDate}`;
      this.boolChangeDate = true;
      this.boolChangeClickType = isYear;
      this.arrYearOrMonthSelect = [];
      let scrollTop;
      if (isYear) {
        const numDate = Number(curDate);
        for (let i = -20; i <= 29; i++) {
          this.arrYearOrMonthSelect.push({ value: numDate + i, type: "year" });
        }
        scrollTop = 3 * (58.5 + 10);
      } else {
        for (let i = 1; i <= 12; i++) {
          this.arrYearOrMonthSelect.push({ value: i, type: "month" });
        }
        scrollTop = 0;
      }
      // 设置初始滚动条位置
      this.$nextTick(() => {
        this.$refs.calendarSelectScroll.scrollTop = scrollTop;
      });
    },

    /**
     *选择指定年月
     * @param selectDate 选取选择项
     * @param curDate 选择年份时传入当前月，选择月份传当前年
     * @param dateType 日期类型 年份/月份
     */
    selectYearOrMonth(selectDate, curDate, dateType) {
      const boolYear = dateType === "year" ? true : false;
      const _d = boolYear
        ? new Date(selectDate, curDate, 0)
        : new Date(curDate, selectDate, 0);
      this.initData(this.formatDate(_d.getFullYear(), _d.getMonth() + 1, 1));
      this.boolChangeDate = false;
      this.boolChangeClickType = dateType === "year" ? true : false;

      this.strChangeActive = `${dateType}_${selectDate}`;
    },
    // 选中天数
    selectedDate(day) {
      console.log(this.currentYear, this.currentMonth, day);
    },
    // 返回yyyy-mm-dd格式的字符串
    formatDate(year, month, day) {
      let y = year;
      let m = month;
      let d = day;
      if (m < 10) m = "0" + m;
      if (d < 10) d = "0" + d;
      return `${y}-${m}-${d}`;
    },
  },
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
};
</script>
<style lang="less" scoped>
.calendar {
  width: 360px;
  height: auto;
  margin: 0 auto;
  overflow: hidden;
  .title_top {
    width: 100%;
    height: 32px;
    line-height: 32px;
    text-align: center;
    background: #eff4ff;
    border: 1px solid #e8e8e8;
    border-bottom: none;
    border-radius: 4px 4px 0px 0px;
    .text {
      font-size: 13px;
      font-family: PingFang SC, PingFang SC-Regular;
      font-weight: 400;
      text-align: center;
      color: #3a444f;
    }
  }
  .calendar_bottom {
    width: 100%;
    height: auto;
    background: #ffffff;
    border: 1px solid #e8e8e8;
    border-radius: 0px 0px 4px 4px;
    padding-bottom: 24px;
    ul {
      list-style-type: none;
      margin-top: 0;
      margin-bottom: 0;
      padding-inline-start: 0px;
    }
    .calendar_b_month {
      width: 100%;
      height: 28px;
      line-height: 28px;
      border-bottom: 1px solid #e8e8e8;
      ul {
        margin: 0;
        padding: 0;
        display: flex;
        justify-content: center;
        li {
          font-size: 13px;
          font-family: PingFang SC, PingFang SC-Medium;
          font-weight: 500;
          text-align: center;
          color: rgba(0, 0, 0, 0.85);
        }
        .calendar_arrow {
          margin: 0 10px;
          font-size: 12px;
          color: rgba(0, 0, 0, 0.45);
          cursor: pointer;
        }
        .calendar_single_arrow {
          margin: 0 10px 0 0;
          font-size: 12px;
          color: rgba(0, 0, 0, 0.45);
        }
        .year_month {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: space-around;
          .choose-month {
            font-size: 13px;
            font-family: PingFang SC, PingFang SC-Medium;
            font-weight: 500;
            text-align: center;
            color: rgba(0, 0, 0, 0.85);
            .choose_month_year:hover {
              color: #3071e8;
              cursor: pointer;
            }
            .choose_month_month {
              margin-left: 5px;
            }
          }
        }
      }
    }
    .calendar_b_weekdays {
      width: auto;
      height: auto;
      font-size: 13px;
      font-family: PingFang SC, PingFang SC-Regular;
      font-weight: 400;
      text-align: center;
      color: rgba(0, 0, 0, 0.85);
      line-height: 20px;
      padding-top: 16px;
      padding-bottom: 4px;
      margin: 0 0 0 24px;
      li {
        width: 24px;
        height: 24px;
        border-radius: 2px;
        margin: 0px 24px 0 0;
        display: inline-block;
      }
      .special_margin_weekdays {
        margin: 0px 23px 0 0;
      }
    }
    .calendar_b_days {
      min-height: 136px;
      padding: 0;
      background: #ffffff;
      margin: 0 0 0 24px;
      .default_days {
        width: 24px;
        height: 24px;
        line-height: 24px;
        background: #f2f4f6;
        border-radius: 2px;
        font-size: 13px;
        font-family: Arial, Arial-Regular;
        font-weight: 400;
        text-align: center;
        color: #434343;
        margin: 10px 24px 0 0;
        list-style-type: none; //是用来移除列表元素默认样式
        display: inline-block;
      }
      .active_days {
        background: #3071e8;
        color: #ffffff;
      }
      .no_current_month_day {
        background: #ffffff;
        color: rgb(255, 255, 255);
      }
      // 特殊的margin格式
      .special_margin_days {
        margin: 10px 23px 0 0;
      }
      .future_days {
        background: #f2f4f6;
        color: #c9c9c9;
      }
    }

    .calendar_b_select {
      min-height: 136px;
      padding: 0;
      background: #ffffff;
      margin: 0 0 0 0;
      overflow-y: scroll;
      margin-left: 24px;
      .calendar_select_default {
        width: 58.5px;
        height: 58.5px;
        margin: 10px 24px 0px 0px;
        background: #f2f4f6;
        list-style-type: none; //是用来移除列表元素默认样式
        display: inline-block;
        font-size: 13px;
        font-family: Arial, Arial-Regular;
        font-weight: 400;
        text-align: center;
        color: #434343;
        line-height: 58.5px;
        &:hover {
          cursor: pointer;
          color: #ffffff;
          background-color: #b6cfff;
        }
      }
      .calendar_select_active {
        background-color: #b6cfff;
        color: #ffffff;
      }
    }
    // 自定义滚动条样式
    .scroll_style::-webkit-scrollbar {
      width: 4px;
      height: 4px;
    }

    .scroll_style::-webkit-scrollbar-thumb {
      width: 4px;
      background: #e0e0e0;
      border-radius: 2px;
    }

    .scroll_style::-webkit-scrollbar-track-piece {
      background: rgb(255, 255, 255);
    }
  }
}
</style>
